package com.itao.springboot.handler;

import com.alibaba.excel.EasyExcel;
import com.itao.springboot.annotation.ExcelExport;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.core.MethodParameter;
import org.springframework.util.Assert;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * Excel返回值解析器
 * @author sjt
 * @Date 2024/12/9 10:08
 */
public class ExcelReturnValueHandler implements HandlerMethodReturnValueHandler {
    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return returnType.hasMethodAnnotation(ExcelExport.class);
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) {
        mavContainer.setRequestHandled(true);
        HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
        Assert.notNull(response, "HttpServletResponse为空");
        ExcelExport excel = returnType.getMethodAnnotation(ExcelExport.class);
        Assert.notNull(excel, "无Excel注解");
        String value = excel.value();
        Class<?> aClass = excel.returnType();

        if (returnValue == null) {
            return;
        }

        if (!(returnValue instanceof List<?> exportList)) {
            throw new RuntimeException("返回值类型必须为List");
        }
        if (exportList.isEmpty() && aClass == void.class) {
            return;
        }
        if (aClass == void.class) {
            aClass = exportList.getFirst().getClass();
        }
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            String fileName = URLEncoder.encode(value + ".xlsx", StandardCharsets.UTF_8);
            response.setHeader("Content-disposition", "attachment;filename=" + fileName);
            OutputStream outputStream = response.getOutputStream();
            EasyExcel.write(outputStream, aClass)
                    .sheet()
                    .doWrite(exportList);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
